unit uWaptMisc;

interface
uses Classes, SysUtils, Registry, Windows, ShellAPI, StrUtils;

PROCEDURE ListInstalledApps(Var aList : TStringList; Verbose : boolean);
PROCEDURE UninstallApp(aAppStr : String);



implementation

function GetEnvVarValue(const VarName: string): string;
var
  BufSize: Integer;  // buffer size required for value
begin
  // Get required buffer size (inc. terminal #0)
  BufSize := GetEnvironmentVariable(
    PChar(VarName), nil, 0);
  if BufSize > 0 then
  begin
    // Read env var value into result string
    SetLength(Result, BufSize - 1);
    GetEnvironmentVariable(PChar(VarName),
      PChar(Result), BufSize);
  end
  else
    // No such environment variable
    Result := '';
end;

PROCEDURE UninstallApp(aAppStr : String);
Var
  aList : TStringList;
  i     : integer;
  x     : integer;
  Temp : string;
  UninstallStr : string;
  UNINSTALLSTRING : String;
Begin
// str representing starting position for actual uninstall string to use to remove app
UNINSTALLSTRING := 'UninstallString:';

// used to generate the command line to uninstall app
UninstallStr := '';

aList := TStringList.Create;

ListInstalledApps(aList,true);

for i := 0 to aList.Count - 1 do
     Begin
     Temp := aList.Strings[i];
     Temp := TrimLeft(Temp);
     Temp := TrimRight(Temp);

     if StrPos(PChar(LowerCase(Temp)), pcHAR(LowerCase(aAppStr))) <> nil then
        Begin
        if StrPos(PChar(Temp), 'ID: ') <> nil then
           Begin
             // start uninstall
             WriteLn('Found');
             // Get the position of this string within Temp
             x := Pos(UNINSTALLSTRING,Temp);
             x := x + Length(UNINSTALLSTRING);

             UninstallStr := RightStr(Temp,(Length(Temp) - X));
             WriteLn(IntToStr(x));

             // start uninstall based on uninstallstr

             if FileExists(UninstallStr) then
                Begin
                ShellExecute(0,'open', PChar(UninstallStr) ,'', nil, SW_SHOWNORMAL) ;
                Exit;
                End
             else
                Begin
                Temp := UninstallStr;
                UninstallStr := '';
                UninstallStr := GetEnvVarValue('SystemRoot') + '\system32\msiexec';
                // remove msi bit from temp
                Temp := StringReplace(Temp, 'MsiExec.exe', '',[rfReplaceAll, rfIgnoreCase]);
                Temp := StringReplace(Temp, '.exe','',[rfReplaceAll,rfIgnoreCase]);
                ShellExecute(0,'open',PChar(UninstallStr), PChar(Temp),nil,sw_shownormal);
                Exit;
                End;
           End
        else
           Begin
             WriteLn('not found');
           End;
        End;
     End;

aList.Free;

End;


PROCEDURE ListInstalledApps(Var aList : TStringList; Verbose : boolean);
Var
  Reg           :     TRegistry;
  KeyList       :     TStringList;
  i             :     integer;
  aString       :     string;
Begin
// Will list all programs correctly installed in windows as seen by viewing
// registry information

KeyList := TStringList.Create;

Reg := TRegistry.Create;
Reg.RootKey := HKEY_LOCAL_MACHINE;

KeyList.BeginUpdate;
// Get List of keys from which we will traverse one by one, reading required data
if reg.openkey(
  'Software\Microsoft\Windows\CurrentVersion\Uninstall\',false) then
     Begin
     Reg.GetKeyNames(KeyList);
     End;
KeyList.EndUpdate;
Reg.CloseKey;

for i := 0 to KeyList.Count - 1 do
     Begin
     if Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Uninstall\' + KeyList.Strings[i] + '\', false) then
        Begin
        if Verbose then
           Begin
           aList.Add(Trim(Reg.ReadString('DisplayName')) + ' version ' +
                     Trim(Reg.ReadString('DisplayVersion')) + ', installed on ' +
                     Trim(Reg.ReadString('InstallDate')) + ', Comments: ' +
                     Trim(Reg.ReadString('Comments')) + ' ID: ' + KeyList.Strings[i] +
                     ' UninstallString: ' + Trim(Reg.ReadString('UninstallString')));


           End
        ELSE
           Begin
           aString := Trim(Reg.ReadString('DisplayName'));
           if aString <> '' then aList.Add(Reg.ReadString('DisplayName'));
           End;
        Reg.CloseKey;
        End;
     End;



Reg.Free;
KeyList.Free;
End;

end.
